//=============================================================================

#ifndef AAUX_H
  #define AAUX_H

//=============================================================================

#include <math.h>
#include "aVector.h"
#include "aList.h"

//=============================================================================

#define MATRIX_SIZE 16

//=============================================================================

#define AUX aAux::aaGetInstance()

//=============================================================================
class aAux
{
  private:
    aAux();
    ~aAux();

  public:
    inline static aAux& aaGetInstance(){static aAux aux; return aux;}
    inline float aaGetPi() {return pi;}
    inline float aaGetPid() {return pid;}
    inline float aaGetPidi() {return pidi;}
    inline float aaGetVersion() {return version;}
    inline aVector aaGetVectorProjection(const aVector& vec, const aVector& vec2) {return vec2*aaDotMulty(vec, vec2);}
    inline float aaGetMagnitude(const aVector& vec) {return sqrt(vec.x*vec.x + vec.y*vec.y + vec.z*vec.z);}
    inline float aaGetMagnitude(float x, float y, float z) {return sqrt(x*x + y*y + z*z);}
    inline float aaDotMulty(const aVector& vec, const aVector& vec2) {return (vec.x*vec2.x + vec.y*vec2.y + vec.z*vec2.z);}
    inline float ator(float angle) {return (angle*pid);}
    inline float aaFloatAbs(float f) {return ((f) < 0.0 ? (-f):f);}
    inline aVector aaVVVXYZ2pos(const aVector& i, const aVector& j, const aVector& k, const aVector& vec) {return (i*vec.x + j*vec.y + k*vec.z);}
    inline aVector aaGetNormal(const aVector& vec, const aVector& vec2, const aVector& vec3) {return aaNormalize(aaCrossMulty((vec2 - vec), (vec3 - vec)));}
    inline bool aaVectorOnLine(const aVector& l1, const aVector& l2, const aVector& p) {return aaCompareFloat(aaGetLength(l1, p) + aaGetLength(l2, p), aaGetLength(l1, l2));}
    inline aVector aaGetAbsVector(const aVector& vec) {return aVector(aaFloatAbs(vec.x), aaFloatAbs(vec.y), aaFloatAbs(vec.z));}
    inline bool aaIsNormal(const aVector& vec) {return (aaCompareFloat(vec.x, 1.0) ? 1:(aaCompareFloat(vec.y, 1.0) ? 1:(aaCompareFloat(vec.z, 1.0) ? 1:0)));}
    inline bool aaIsVectorNULL(const aVector& vec) {return (aaCompareFloat(vec.x, 0.0f) ? (aaCompareFloat(vec.y, 0.0f) ? (aaCompareFloat(vec.z, 0.0f) ? 1:0):0):0);}
    inline aVector aaGetNullVector() {return aVector();}

    //uVector
    aVector aaCrossMulty(const aVector& vec, const aVector& vec2);
    aVector aaNormalize(const aVector& v);
    float aaGetAngle(const aVector& v, const aVector& v2);
    aVector aaRotateAroundVector(const aVector& v, const aVector& v2, float angle);
    bool aaCompareFloat(float f1, float f2);
    bool aaCompareFloatHigh(float f, float f2);
    float aaGetLength(const aVector& vec, const aVector& vec2);
    bool aaCheckVectorIn(const aVector& p, const aVector& vec1, const aVector& vec2, const aVector& vec3);
    aVector aaGetIntersection(const aVector& l1, const aVector& l2, const aVector& s1, const aVector& s2, const aVector& s3);
    aVector aaGetLinesIntersection(const aVector& p11, const aVector& p12, const aVector& p21, const aVector& p22, const aVector& n);
    aVector aaGetClosestPoint(const aVector& p1, const aVector& p2, const aVector& wp);

  public:
    float dt;

  private:
    float pi;
    float pid;
    float pidi;
    float version;
};

//=============================================================================

#endif

//=============================================================================
